package ihm;

import controller.AscenseurControleur;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Font;
import javax.swing.*;
import javax.swing.table.DefaultTableCellRenderer;
import model.Ascenseur;
import util.Observeur;

/**
 * Classe qui affiche, dans la partie droite de la fenêtre, le tableau représentant l'ensemble du bâtiment.
 * 
 * @author Jason
 */
public class TableauAscenseurs implements Observeur {
    private JTable tableau;
    private JScrollPane scrollPane;

    private final int nbLignes = 45;

    private final Color couleurHeader = new Color(51,102,255);
    
    private AscenseurControleur ascenseurControleur;

    /**
     * Constructeur.
     */
    public TableauAscenseurs(AscenseurControleur ascenseurControleur) {
        this.ascenseurControleur = ascenseurControleur;
        this.ascenseurControleur.ajouterObserveur(this);
        
        String[] titreColonnes = {"Etages", "1","2", "3","4", "5", "6"}; 

        //Initialisation d'un tableau de 7 colonnes et 45 lignes
        tableau = new JTable(new Object[nbLignes][titreColonnes.length], titreColonnes) {
                private static final long serialVersionUID = 1L;
                public boolean isCellEditable(int rowIndex, int colIndex) {
                            return false;
                    }
        };
        tableau.setBorder(BorderFactory.createLineBorder(Color.black));

        //Création des numéros d'étage.
        int cptLignes=0;
        for(int i=40;i>=-4;i--) {
                tableau.setValueAt(i, cptLignes, 0);
                cptLignes++;
        }

        scrollPane = new JScrollPane(tableau);

        tableau.setDefaultRenderer(Object.class, new TableauRenderer());
    }

    /**
     * Affiche ou met à jour la position d'un ascenseur dans le tableau.
     * 
     * @param numeroAscenseur	numéro de l'ascenseur à mettre à jour.
     * @param etage				nouvelle position de l'ascenseur.
     */
    public void setPositionAscenseur(int etage, int numeroAscenseur) {
//	tableau.setDefaultRenderer(Object.class, new MonCellRenderer(tableau, etage, numeroAscenseur));
        tableau.getColumnModel().getColumn(numeroAscenseur).setCellRenderer(new AscenseurRenderer(tableau, etage, numeroAscenseur));
    }
    
    @Override
    public void update() {
        for(Integer i : ascenseurControleur.getAllNumeroAscenseur()) {
            setPositionAscenseur(ascenseurControleur.getEtageCourant(i), i);
        }
        this.getTableau().repaint();
    }
	
    /**
     * Classe interne permettant la mise en forme du tableau d'ascenseurs.
     */
    public class TableauRenderer extends DefaultTableCellRenderer {

            private static final long serialVersionUID = 1L;

            /**
             * Constructeur.
             */
            public TableauRenderer() {

                    Font policeTitres = new Font("Arial",Font.PLAIN,13);

                    //Centrer le contenu des cellules du tableau.
                    this.setHorizontalAlignment(JLabel.CENTER);

                    //Mise en forme du header du tableau.
                    tableau.getTableHeader().setFont(policeTitres);
                    tableau.getTableHeader().setBackground(couleurHeader);

                    //Désactiver la sélection d'une ligne, d'une colonne, et d'une cellule au moment d'un click sur le tableau.
                    tableau.setRowSelectionAllowed(false);
                    tableau.setColumnSelectionAllowed(false);
                    tableau.setRequestFocusEnabled(false);

                    //Calcul du recentrage du tableau.
                    Dimension dimScrollPane = scrollPane.getPreferredSize();
                    int hauteurHeader = tableau.getRowHeight();
                    int hauteurFenetre = tableau.getPreferredSize().height;
                    //La hauteur du header n'est pas comptée dans la hauteur du tableau : il faut donc la retirer.
                    int hauteurTableau = dimScrollPane.height + hauteurHeader;
                    int marge = (hauteurFenetre - hauteurTableau - hauteurHeader)/2;
//			scrollPane.setBorder(				
//					BorderFactory.createEmptyBorder(
//							marge,0,0,0
//					)
//			);
            }
    }
	
    /**
     * Classe interne qui permet la mise en forme d'une cellule associée au mouvement d'un ascenseur.
     */
    public class AscenseurRenderer extends TableauRenderer {
            private static final long serialVersionUID = 1L;
            private int numeroAscenseur;
            private int etage;

            /**
             * Constructeur.
             * 
             * @param table
             * @param etage
             * @param numeroAscenseur
             */
            public AscenseurRenderer(JTable table, int etage, int numeroAscenseur) {
                    this.numeroAscenseur = numeroAscenseur;
                    this.etage = 40 - etage;
                    this.getTableCellRendererComponent(table, null,
                                    true, true, 0, 0);
            }

            /**
             * Redéfinition de la méthode de la super-classe.
             * 
             * @param table
             * @param value
             * @param isSelected
             * @param hasFocus
             * @param row
             * @param column
             */
            public Component getTableCellRendererComponent(JTable table, Object value,
                            boolean isSelected, boolean hasFocus, int row, int column) {
                
                Ascenseur as = null;
                String pathImg = null;
                JLabel cell = (JLabel) super.getTableCellRendererComponent(table, value,
                                isSelected, hasFocus, row, column);

                if (row == etage && column == numeroAscenseur) {
                    //cell.setBackground(Color.RED);
                    as = ascenseurControleur.getAscenseur(numeroAscenseur);
                    if(as != null) {
                        if(as.getDirectionActuel() == Ascenseur.IMMOBILE) {
                            if(as.isPorteOuverte()) {
                                pathImg = "src/Icone_ascenseur/Libre_Vert_ouvert.png";
                            } else {
                                pathImg = "src/Icone_ascenseur/Libre_Vert_ferme.png";
                            }
                            
                            if(as.getDelaiAvantProchaineEtage() == 1) {
                                pathImg = "src/Icone_ascenseur/Fermeture_porte_Orange_pleine_parfait.png";
                            } else if (as.getDelaiAvantProchaineEtage() == 5) {
                                pathImg = "src/Icone_ascenseur/Ouverture_porte_Orange_pleine_parfait.png";
                            }
                        } else if(as.getDirectionActuel() == Ascenseur.MONTEE){
                            // TODO : Gérer si ascenseur avec personne ou pas
                            pathImg = "src/Icone_ascenseur/Occupe_Rouge_Monte.png";
                        } else if(as.getDirectionActuel() == Ascenseur.DESCENTE){
                            // TODO : Gérer si ascenseur avec personne ou pas
                            pathImg = "src/Icone_ascenseur/Occupe_Rouge_Descend.png";
                        }
                    }
                    //System.out.println(new java.io.File(new java.io.File("").getAbsolutePath()));
                    pathImg = System.getProperty("java.class.path").replace("\\", "/") + "/../../" + pathImg;
                    //System.out.println(pathImg);
                    cell.setIcon(new ImageIcon(pathImg));
                    //PanelTraceExecution.ecrireTraceExecution(String.valueOf(tableau.getColumnModel().getColumn(1).getWidth()));
                } else {
                    cell.setIcon(null);
                    //cell.setBackground(Color.WHITE);
                }
                return cell;
            }
    }
	
    public JTable getTableau() {
            return tableau;
    }

    public void setTableau(JTable tableau) {
            this.tableau = tableau;
    }

    public JScrollPane getScrollPane() {
            return scrollPane;
    }

    public void setScrollPane(JScrollPane scrollPane) {
            this.scrollPane = scrollPane;
    }
}
